﻿/*
 * KLF Headless Browser
 * Written by Kris Oye <kristianoye@gmail.com>
 * Copyright (C) 2011-2012.  All rights reserved.
 */
namespace KLF.Lib.Browser.DOM.HTML
{
    #region Using Statements

    using System;
    using System.Linq;

    #endregion

    public class HTMLTableCellElement : HTMLBlockBaseElement
    {
        #region Constructors

        internal HTMLTableCellElement(Document owner)
            : base(owner, HTMLConstants.HTML_TAG_TABLECELL)
        {
        }

        #endregion

        #region HTML Level 2 DOM Compliance

        /// <summary>
        /// Abbreviation for header cells. See the abbr attribute definition
        /// in HTML 4.01.
        /// </summary>
        public string abbr
        {
            get
            {
                return getAttribute(HTMLConstants.HTML_ATT_ABBR);
            }
            set
            {
                if (String.IsNullOrEmpty(value))
                    removeAttribute(HTMLConstants.HTML_ATT_ABBR);
                else
                    setAttribute(HTMLConstants.HTML_ATT_ABBR, value);
            }
        }

        /// <summary>
        /// Names group of related headers. See the axis attribute definition
        /// in HTML 4.01.
        /// </summary>
        public string axis
        {
            get
            {
                return getAttribute(HTMLConstants.HTML_ATT_AXIS);
            }
            set
            {
                if (String.IsNullOrEmpty(value))
                    removeAttribute(HTMLConstants.HTML_ATT_AXIS);
                else
                    setAttribute(HTMLConstants.HTML_ATT_AXIS, value);
            }
        }

        /// <summary>
        /// Cell background color. See the bgcolor attribute definition in 
        /// HTML 4.01. This attribute is deprecated in HTML 4.01.
        /// </summary>
        [Obsolete]
        public string bgColor
        {
            get
            {
                return getAttribute(HTMLConstants.HTML_ATT_BGCOLOR);
            }
            set
            {
                if (String.IsNullOrEmpty(value))
                    removeAttribute(HTMLConstants.HTML_ATT_BGCOLOR);
                else
                    setAttribute(HTMLConstants.HTML_ATT_BGCOLOR, value);
            }
        }

        /// <summary>
        /// The index of this cell in the row, starting from 0. This index is 
        /// in document tree order and not display order.
        /// </summary>
        public int cellIndex
        {
            get
            {
                HTMLTableRowElement r = rowElement;

                if (r != null)
                {
                    HTMLCollection c = r.cells;
                    return c.Nodes.IndexOf(this);
                }
                return -1;
            }
        }

        /// <summary>
        /// Alignment character for cells in a column. 
        /// 
        /// See the char attribute definition in HTML 4.01.
        /// </summary>
        public string ch
        {
            get
            {
                return getAttribute(HTMLConstants.HTML_ATT_CHAR);
            }
            set
            {
                if (String.IsNullOrEmpty(value))
                    removeAttribute(HTMLConstants.HTML_ATT_CHAR);
                else
                    setAttribute(HTMLConstants.HTML_ATT_CHAR, value);
            }
        }

        /// <summary>
        /// Offset of alignment character. 
        /// 
        /// See the charoff attribute definition in HTML 4.01.
        /// </summary>
        public string chOff
        {
            get
            {
                return getAttribute(HTMLConstants.HTML_ATT_CHAROFF);
            }
            set
            {
                if (String.IsNullOrEmpty(value))
                    removeAttribute(HTMLConstants.HTML_ATT_CHAROFF);
                else
                    setAttribute(HTMLConstants.HTML_ATT_CHAROFF, value);
            }
        }

        /// <summary>
        /// Number of columns spanned by cell. See the colspan attribute 
        /// definition in HTML 4.01.
        /// </summary>
        public int colSpan
        {
            get
            {
                return getAttributeAsType<int>(HTMLConstants.HTML_ATT_COLSPAN, 1);
            }
            set
            {
                if (value > 0)
                {
                    setAttributeAsType<int>(HTMLConstants.HTML_ATT_COLSPAN, value);
                }
            }
        }

        /// <summary>
        /// List of id attribute values for header cells. See the headers 
        /// attribute definition in HTML 4.01.
        /// </summary>
        public string headers
        {
            get
            {
                return getAttribute(HTMLConstants.HTML_ATT_HEADERS);
            }
            set
            {
                if (String.IsNullOrEmpty(value))
                    removeAttribute(HTMLConstants.HTML_ATT_HEADERS);
                else
                    setAttribute(HTMLConstants.HTML_ATT_HEADERS, value);
            }
        }

        /// <summary>
        /// Cell height. See the height attribute definition in HTML 4.01. 
        /// 
        /// This attribute is deprecated in HTML 4.01.
        /// </summary>
        [Obsolete]
        public string height
        {
            get
            {
                return getAttribute(HTMLConstants.HTML_ATT_HEIGHT);
            }
            set
            {
                if (String.IsNullOrEmpty(value))
                    removeAttribute(HTMLConstants.HTML_ATT_HEIGHT);
                else
                    setAttribute(HTMLConstants.HTML_ATT_HEIGHT, value);
            }
        }

        /// <summary>
        /// Suppress word wrapping. See the nowrap attribute definition in 
        /// HTML 4.01. This attribute is deprecated in HTML 4.01.
        /// </summary>
        [Obsolete]
        public string noWrap
        {
            get
            {
                return getAttribute(HTMLConstants.HTML_ATT_NOWRAP);
            }
            set
            {
                if (String.IsNullOrEmpty(value))
                    removeAttribute(HTMLConstants.HTML_ATT_NOWRAP);
                else
                    setAttribute(HTMLConstants.HTML_ATT_NOWRAP, value);
            }
        }

        /// <summary>
        /// Number of rows spanned by cell. See the rowspan attribute definition 
        /// in HTML 4.01.
        /// </summary>
        public int rowSpan
        {
            get
            {
                return getAttributeAsType<int>(HTMLConstants.HTML_ATT_ROWSPAN, 1);
            }
            set
            {
                if (value > 0)
                {
                    setAttributeAsType<int>(HTMLConstants.HTML_ATT_ROWSPAN, value);
                }
            }
        }

        /// <summary>
        /// Custom attribute -- Returns containing row
        /// </summary>
        public HTMLTableRowElement rowElement
        {
            get
            {
                HTMLElement p = this;
                do
                {
                    if (p is HTMLTableRowElement)
                        return (HTMLTableRowElement)p;
                    p = p.Parent as HTMLElement;
                }
                while (p != null);
                return null;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public string scope
        {
            get
            {
                return getAttribute(HTMLConstants.HTML_ATT_SCOPE);
            }
            set
            {
                if (String.IsNullOrEmpty(value))
                    removeAttribute(HTMLConstants.HTML_ATT_SCOPE);
                else
                {
                    switch(value.ToLowerInvariant())
                    {
                        case "row":
                        case "col":
                        case "rowgroup":
                        case "colgroup":
                            setAttribute(HTMLConstants.HTML_ATT_SCOPE, value);
                            break;
                        default:
                            Owner.AddError("Element {0} had invalid value '{1}' for attribute {2}",
                                tagName, value, HTMLConstants.HTML_ATT_SCOPE);
                            break;
                    }
                }
            }
        }

        /// <summary>
        /// Indicates the number of columns in a group or affected by a 
        /// grouping. See the span attribute definition in HTML 4.01.
        /// </summary>
        public int span
        {
            get
            {
                return getAttributeAsType<int>(HTMLConstants.HTML_ATT_SPAN, 1);
            }
            set
            {
                setAttributeAsType<int>(HTMLConstants.HTML_ATT_SPAN, value);
            }
        }

        /// <summary>
        /// Vertical alignment of cell data in column. 
        /// 
        /// See the valign attribute definition in HTML 4.01.
        /// </summary>
        public string vAlign
        {
            get
            {
                return getAttribute(HTMLConstants.HTML_ATT_VALIGN);
            }
            set
            {
                if (String.IsNullOrEmpty(value))
                    removeAttribute(HTMLConstants.HTML_ATT_VALIGN);
                else
                    setAttribute(HTMLConstants.HTML_ATT_VALIGN, value);
            }
        }


        /// <summary>
        /// Default column width. 
        /// 
        /// See the width attribute definition in HTML 4.01.
        /// </summary>
        public string width
        {
            get
            {
                return getAttribute(HTMLConstants.HTML_ATT_WIDTH);
            }
            set
            {
                if (String.IsNullOrEmpty(value))
                    removeAttribute(HTMLConstants.HTML_ATT_WIDTH);
                else
                    setAttribute(HTMLConstants.HTML_ATT_WIDTH, value);
            }
        }

        #endregion

        #region Custom Attributes

        /// <summary>
        /// Returns the containing table element or null if unattached.
        /// </summary>
        public HTMLTableElement tableElement
        {
            get
            {
                HTMLElement p = this;

                do
                {
                    p = p.Parent as HTMLElement;
                }
                while ((p != null) && !(p is HTMLTableElement));

                return (p != null ? p as HTMLTableElement : null);

            }
        }

        #endregion
    }
}
